#include <dbentity/T_XG_FILE.h>
#include <dbentity/T_XG_NOTE.h>
#include <webx/route.h>

class NoteFile : public webx::ProcessBase
{
protected:
	int process();
};

HTTP_WEBAPP(NoteFile)

int NoteFile::process()
{
	string user;

	param_string(flag);
	param_string(dbid);
	param_name_string(id);

	auto processJson = [&](string path){
		int res = 0;
		CT_XG_FILE tf;
		CT_XG_NOTE tab;
		SmartBuffer content;
		sp<DBConnect> dbconn = webx::GetDBConnect(ctx, dbid);

		tab.init(dbconn);
		tab.id = id;

		if (!tab.find()) throw Exception(XG_SYSERR);
		if (!tab.next()) throw Exception(XG_NOTFOUND);
		if (user != tab.user.val()) throw Exception(XG_NOTFOUND);
		if (stdx::GetFileContent(content, path = app->getPath() + path) <= 0) throw Exception(XG_PARAMERR);

		tf.init(dbconn);
		tf.type = "NOTE";
		tf.rid = tab.id;
		tf.content = content;
		tf.statetime.update();
		tf.imme = app->getMimeType(stdx::tolower(path::extname(path)));

		for (int i = 0; i < 5; i++)
		{
			tf.id = DateTime::GetBizId();

			if ((res = tf.insert()) >= 0) break;
		}

		if (res < 0) throw Exception(XG_SYSERR);

		if (dbid.empty())
		{
			json["url"] = "/notefile?id=" + tf.id.val();
		}
		else
		{
			json["url"] = "/notefile?id=" + tf.id.val() + "&dbid=" + dbid;

			path::remove(path);
		}

		json["code"] = XG_OK;
		out << json;

		return XG_OK;
	};
	
	auto processFile = [&](sp<QueryResult> rs){
		if (!rs) throw Exception(XG_SYSERR);

		sp<RowData> row = rs->next();
	
		if (!row) throw Exception(XG_NOTFOUND);

		DateTime utime;
		SmartBuffer data = row->getBinary(1);

		if (data.size() > 0xFF && row->getDateTime(utime, 2))
		{
			char etag[64];
			string version = request->getHeadValue("If-None-Match");

			sprintf(etag, "%ld:%d", utime.getTime(), data.size());

			if (version == etag) throw Exception(XG_NOTCHANGED);

			response->setHeadValue("ETag", etag);
		}

		createFile(data.size());
		
		response->setContentType(row->getString(0));

		return file->write(data.str(), data.size());
	};

	try
	{
		user = checkLogin();

		if (dbid.empty()) dbid = token->getDataId();
	}
	catch (Exception e)
	{
	}

	if (flag == "S")
	{
		if (user.empty()) throw Exception(XG_TIMEOUT);

		param_path_string(path);

		return processJson(path);
	}
	else if (user.empty())
	{
		string sqlcmd = "SELECT b.IMME,b.CONTENT,b.STATETIME FROM T_XG_NOTE a,T_XG_FILE b WHERE a.ID=b.RID AND b.ID=? AND a.LEVEL>2";
		
		return processFile(webx::GetDBConnect(ctx, dbid)->query(sqlcmd, id));
	}
	else
	{
		string sqlcmd = "SELECT b.IMME,b.CONTENT,b.STATETIME FROM T_XG_NOTE a,T_XG_FILE b WHERE a.ID=b.RID AND b.ID=? AND (a.USER=? OR a.LEVEL>2)";

		return processFile(webx::GetDBConnect(ctx, dbid)->query(sqlcmd, id, user));
	}
}